package cn.jtfadmin.support.modules.mail;

import cn.jtfadmin.support.modules.mail.dto.AbstractSendMailDTO;
import cn.jtfadmin.support.modules.mail.dto.AttachmentSendMailDTO;
import cn.jtfadmin.support.modules.mail.dto.HtmlSendMailDTO;
import cn.jtfadmin.support.modules.mail.dto.TextSendMailDTO;
import org.apache.commons.mail.*;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.Objects;

/**
 * 邮件支持类库, 使用apache commons email
 * @author jtf
 * @since 0.0.2
 */
public class MailSupport {


    private static ThreadLocal<Email> threadLocal = new ThreadLocal<>();

    /**
     * 发送文本消息
     * @param dto 文本消息配置
     * @return 消息id
     * @throws EmailException
     */
    public static String send(TextSendMailDTO dto) throws EmailException {
        try{
            Email email = threadLocal.get();
            if(email == null){
                email = new SimpleEmail();
                threadLocal.set(email);
            }
            email.setMsg(dto.getMsg());
            return send((AbstractSendMailDTO)dto);
        }finally {
            threadLocal.remove();
        }


    }

    /**
     * 发送附件
     * @param dto 附件消息配置
     * @return 消息id
     * @throws EmailException
     */
    public static String send(AttachmentSendMailDTO dto) throws EmailException, MalformedURLException {
        try{
            List<AttachmentSendMailDTO.AttachmentDTO> attachmentList = dto.getAttachmentList();
            if(CollectionUtils.isEmpty(attachmentList)){
                return send((TextSendMailDTO)dto);
            }
            MultiPartEmail email = (MultiPartEmail)threadLocal.get();
            if(email == null){
                email = new MultiPartEmail();
                threadLocal.set(email);
            }
            for (AttachmentSendMailDTO.AttachmentDTO attachmentDTO : attachmentList) {
                EmailAttachment emailAttachment = new EmailAttachment();
                emailAttachment.setDescription(attachmentDTO.getDescription());
                emailAttachment.setName(attachmentDTO.getName());
                emailAttachment.setPath(attachmentDTO.getPath());
                if(StringUtils.hasText(attachmentDTO.getUrl())){
                    emailAttachment.setURL(new URL(attachmentDTO.getUrl()));
                }

                email.attach(emailAttachment);
            }
            return send((TextSendMailDTO) dto);
        }finally {
            threadLocal.remove();
        }

    }

    /**
     * 发送附件
     * @param dto 附件消息配置
     * @return 消息id
     * @throws EmailException
     */
    public static String send(HtmlSendMailDTO dto) throws EmailException, MalformedURLException {
        try{

            HtmlEmail email = new HtmlEmail();
            threadLocal.set(email);
            if(StringUtils.hasText(dto.getTextMsg())){
                email.setTextMsg(dto.getTextMsg());
            }
            return send((AttachmentSendMailDTO) dto);
        }finally {
            threadLocal.remove();
        }

    }

    /**
     * 发送消息
     * @param dto 发送配置
     * @return 消息id
     * @throws EmailException
     */
    private static String send(AbstractSendMailDTO dto) throws EmailException {
        try{
            Email email = threadLocal.get();
            email.setCharset("utf-8");
            email.setHostName(dto.getSmtpHostName());
            if(Objects.nonNull(dto.getSmtpPort())){
                email.setSmtpPort(dto.getSmtpPort());
            }
            email.setAuthenticator(new DefaultAuthenticator(dto.getAuthenticatorUsername(), dto.getAuthenticatorPassword()));
            email.setSSLOnConnect(dto.isSslOnConnect());
            email.setFrom(dto.getFrom().getAddress(), dto.getFrom().getName());

            email.setSubject(dto.getSubject());
            for (AbstractSendMailDTO.MailAddressDTO mailAddressDTO : dto.getToList()) {
                email.addTo(mailAddressDTO.getAddress(), mailAddressDTO.getName());
            }
            for (AbstractSendMailDTO.MailAddressDTO mailAddressDTO : dto.getReplyTo()) {
                email.addReplyTo(mailAddressDTO.getAddress(), mailAddressDTO.getName());
            }
            return email.send();
        }finally {
            threadLocal.remove();
        }

    }




}
